package repository

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Number"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/OS"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/periodTask"
	"go-fox-edge-kernel-manager/utils/ProcessUtils"
)

type repoLocalProcessGcTask struct {
	statusMap map[string]interface{}
}

func (e *repoLocalProcessGcTask) TaskType() periodTask.TaskType {
	return periodTask.TaskShare
}

func (e *repoLocalProcessGcTask) SchedulePeriod() int64 {
	return 60
}

func (e *repoLocalProcessGcTask) Execute() {
	// windows版本没有对操作系统进行CleanCache的操作
	if OS.Type.IsWindows() {
		return
	}

	// 通过PS命令获得进程列表
	processList, err := ProcessUtils.GetProcessAll()
	if err != nil {
		return
	}

	// 逐个对进程进行GC操作
	for _, data := range processList {
		pid := Map.GetInt64(data, "pid", 0)
		rss := Map.GetInt64(data, "rss", 0)
		appEngine := Map.GetString(data, "appEngine", "")

		if "java" != appEngine || pid == 0 {
			continue
		}

		// 取出上次保存的进程内存大小
		val, err := Map.GetValue(e.statusMap, "Process GC", "rss", pid)
		if err != nil {
			continue
		}
		rssLast := Number.MakeInt64(val)

		// 检查：内存的膨胀状况，是否超过50M内存
		if rss < rssLast+50*1000 {
			continue
		}

		// 膨胀过大的进程，进行GC回收过期内存
		ProcessUtils.GcProcess(pid)

		// 获得GC后进程的内存占用大小
		rssNew, err := e.getRSS(pid)
		if err != nil {
			continue
		}

		// 将本次内存大小保存下来
		Map.SetValue(e.statusMap, "Process GC", "rss", pid, rssNew)

	}

}

func (e *repoLocalProcessGcTask) getRSS(processId int64) (int64, error) {
	// 获得进程列表信息
	processList, err := ProcessUtils.GetProcessAll()
	if err != nil {
		return 0, err
	}

	// 找到指定PID的RSS
	for _, data := range processList {
		pid := Map.GetInt64(data, "pid", 0)
		rss := Map.GetInt64(data, "rss", 0)

		if processId == pid {
			return rss, nil
		}
	}

	return 0, errors.New("找不到指定的进程")
}
